# coding: utf-8

"""Main module."""


import argparse
from bs4 import BeautifulSoup
import hashlib
import re
import redis
import requests
import sleekxmpp
import subprocess
import tempfile


BASE_URL = ('http://www.germania.diplo.de')
RESULTS_PAGE_URL = BASE_URL + ('/Vertretung/russland/ru/02-mosk/1-visa'
                               '/4-passausgabe/0-passausgabe.html')


class SendMsgBot(sleekxmpp.ClientXMPP):

    def __init__(self, jid, password, recipients, msg):
        super(SendMsgBot, self).__init__(jid, password)
        self.recipients = recipients
        self.msg = msg

        self.add_event_handler('ssl_invalid_cert', lambda: None)
        self.add_event_handler('session_start', self.start)

    def start(self, event):
        self.send_presence()
        self.get_roster()

        for recipient in self.recipients:
           self.send_message(mto=recipient, mbody=self.msg)

        self.disconnect(wait=True)



def compare_and_store(digest):
    r = redis.StrictRedis(host='localhost')
    old_digest = r.get('digest')
    r.set('digest', digest)
    if old_digest is None:
        return None
    return digest == old_digest


def check(number):
    resp = requests.get(RESULTS_PAGE_URL)
    soup = BeautifulSoup(resp.text, 'html.parser')
    results_link = soup.find_all('a', string=re.compile(u'Обработанные'))[0]
    resp = requests.get(BASE_URL + results_link['href'])
    # bufsize=0 below is required because sometimes the file is not written
    # completely and i don't know how to force it without closing the file.
    # I don't want to close the file because i don't want to handle deletion
    # myself.
    pdf_file = tempfile.NamedTemporaryFile(mode='w+b', bufsize=0,
                                           suffix='.pdf')
    pdf_file.write(resp.content)
    text = subprocess.check_output(['pdftotext', pdf_file.name, '-'])
    digest = hashlib.sha256(resp.content).hexdigest()
    not_changed = compare_and_store(digest)
    return (str(number) in text, not_changed)


def message_result(result, from_, to):
    sender, password = from_.split(':')
    xmpp = SendMsgBot(sender, password, to.split(','), result)
    xmpp.register_plugin('xep_0030') # Service Discovery
    xmpp.register_plugin('xep_0199') # XMPP Ping

    if xmpp.connect():
        xmpp.process(block=True)


def main():
    parser = argparse.ArgumentParser(description='Check application number.')
    parser.add_argument('number', metavar='N', help='number')
    parser.add_argument('--from', help='number')
    parser.add_argument('--to', help='number')

    args = parser.parse_args()
    found, not_changed = check(args.number)
    if found:
        result = 'Application found'
    else:
        result = 'Application NOT found'
    if not_changed:
        if not_changed is None:
            print('Old state is not known')
        else:
            print('The file has not changed')
    else:
        print('The file has changed')
        if args.to:
            mail_result(result, vars(args)['from'], args.to)


if __name__ == '__main__':
    main()
